<template>
  <a-button
    @click="clickBtn('add')"
    shape="round"
    :style="{
      position: 'fixed',
      top: 'calc(100vh - 150px)',
      left: 'calc(100vw - 80px)',
      zIndex: '9999',
    }"
  >
    <PlusOutlined />
  </a-button>
  <a-button
    @click="clickBtn('subtract')"
    shape="round"
    :style="{
      position: 'fixed',
      top: 'calc(100vh - 100px)',
      left: 'calc(100vw - 80px)',
      zIndex: '9999',
    }"
  >
    <MinusOutlined />
  </a-button>
  <div v-loading="loading" style="position: relative">
    <div ref="environment"></div>
  </div>
</template>

<script lang="ts">
  import { defineComponent, ref, onMounted } from 'vue';
  import * as THREE from 'three';
  import { PlusOutlined, MinusOutlined } from '@ant-design/icons-vue';
  import { OrbitControls } from 'https://threejsfundamentals.org/threejs/resources/threejs/r122/examples/jsm/controls/OrbitControls.js';
  export default defineComponent({
    // 传入六张图
    components: { MinusOutlined, PlusOutlined },
    props: {
      photos: {
        type: Array,
      },
      minFov: {
        type: Number as PropType<string>,
      },
      maxFov: {
        type: Number as PropType<string>,
      },
    },
    setup(props, {}) {
      const loading = ref(true);
      const fov = ref<Number>(75);
      const near = ref<Number>(props.minFov ? props.minFov : 20);
      const far = ref<Number>(props.maxFov ? props.maxFov : 100);
      const camera = new THREE.PerspectiveCamera(
        props.fov ? props.fov : fov.value,
        window.innerWidth / window.innerHeight,
        near.value,
        far.value,
      );

      /**
       * antialias消除锯齿
       */
      const renderer = new THREE.WebGLRenderer({ antialias: true });
      const scene: any = new THREE.Scene();

      const environment = ref<HTMLDivElement>();

      // const scrollFunc = function (e) {
      //   e = e || window.event;
      //   if (e.wheelDelta) {
      //     //判断浏览器IE，谷歌滑轮事件
      //     if (e.wheelDelta > 0) {
      //       //当滑轮向上滚动时
      //       alert('滑轮向下滚动');
      //     }
      //     if (e.wheelDelta < 0) {
      //       //当滑轮向下滚动时
      //       alert('滑轮向上滚动');
      //     }
      //   } else if (e.detail) {
      //     //Firefox滑轮事件
      //     if (e.detail > 0) {
      //       //当滑轮向上滚动时
      //       alert('滑轮向下滚动');
      //     }
      //     if (e.detail < 0) {
      //       //当滑轮向下滚动时
      //       alert('滑轮向上滚动');
      //     }
      //   }
      // };

      function clickBtn(type) {
        //e.stopPropagation();
        if (type == 'subtract') {
          if (fov.value > near.value) fov.value = fov.value - 10;
        }
        if (type == 'add') {
          if (fov.value < far.value) fov.value = fov.value + 10;
        }
        camera.fov = fov.value;
        camera.updateProjectionMatrix();
        renderer.render(scene, camera);
      }

      /**
       * 初始化
       */
      const init = () => {
        loading.value = true;
        /**
         * 相机 PerspectiveCamera(视野大小, 视图的长宽比, 近景， 远景)
         */
        camera.position.set(0, 0, 300);
        camera.lookAt(scene.position);
        // 背景颜色
        renderer.setClearColor(0xffffff);
        // 设置设备像素比
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(window.innerWidth, window.innerHeight);

        /**
         * 添加环境灯光
         */
        scene.add(new THREE.AmbientLight(0xffffff, 2));

        environment.value?.appendChild(renderer.domElement);

        const planeGeometry = new THREE.PlaneGeometry(0, 0);
        // 材质 MeshBasicMaterial和MeshLambertMaterial的区别 MeshLambertMaterial它不会自己发光,而是需要一个光源照射
        const planeMaterial = new THREE.MeshLambertMaterial({ color: 0xcccccc });
        // 用来定位音源的网格模型
        const audioMesh = new THREE.Mesh(planeGeometry, planeMaterial);
        // 设置网格模型的位置，相当于设置音源的位置
        audioMesh.position.set(0, 0, 300);
        scene.add(audioMesh);

        window.addEventListener('resize', () => onWindowResize());
        /**
         * 轨道控制器 也就是鼠标转动等操作
         */
        let orbitControls = new OrbitControls(camera, renderer.domElement);
        orbitControls.autoRotateSpeed = 1;
        orbitControls.minDistance = 50;

        renderScene();
        function renderScene() {
          requestAnimationFrame(renderScene);
          renderer.render(scene, camera);
        }

        const onWindowResize = () => {
          renderer.setSize(window.innerWidth, window.innerHeight);
          camera.aspect = window.innerWidth / window.innerHeight;
          camera.updateProjectionMatrix();
        };
      };

      onMounted(() => {
        init();
        loading.value = true;
        scene.background = new THREE.CubeTextureLoader()
          .setPath(`/`)
          .load(props.photos, function () {
            loading.value = false;
          });
      });

      return {
        environment,
        loading,
        clickBtn,
        fov,
        near,
        far,
      };
    },
  });
</script>
